This document is an attempt to reproduce some of the charts shown in Observable Plot documentation.

Facets

data(anscombe_obs)

obsplot(anscombe_obs, height = 240) |>
    mark_frame() |>
    mark_dot(x = "x", y = "y") |>
    facet(x = "series") |>
    opts(grid = TRUE, inset = 10)
data(barley)
# precompute domains
y_domain <- reorder(barley$variety, barley$yield, median) |> levels() |> rev()
fy_domain <- reorder(barley$site, barley$yield, median) |> levels() |> rev()

obsplot(barley, height = 800) |>
    mark_frame() |>
    mark_dot(x = "yield", y = "variety", stroke = "year") |>
    facet(y = "site", marginRight = 90) |>
    scale_x(nice = TRUE) |>
    scale_y(domain = y_domain, inset = 5) |>
    scale_fy(domain = fy_domain) |>
    scale_color(type = "categorical") |>
    opts(marginLeft = 110, grid = TRUE)
library(palmerpenguins)
data(penguins)

obsplot(penguins, height = 600) |>
    mark_frame() |>
    mark_dot(penguins, x = "bill_depth_mm", y = "bill_length_mm", r = 2, fill = "#ddd") |>
    mark_dot(x = "bill_depth_mm", y = "bill_length_mm") |>
    facet(x = "sex", y = "species", marginRight = 80) |>
    opts(grid = TRUE)

Group transform

data(penguins)

obsplot(penguins) |>
    mark_barY(transform_groupX(y = "count", x = "species")) |>
    mark_ruleY(0) |>
    scale_y(grid = TRUE)
obsplot(penguins) |>
    mark_barY(transform_groupX(y = "count", x = "species")) |>
    mark_ruleY(0) |>
    scale_x(domain = names(sort(table(penguins$species))), reverse = TRUE) |>
    scale_y(grid = TRUE)
obsplot(penguins) |>
    mark_barY(transform_groupX(y = "proportion", x = "species")) |>
    mark_ruleY(0) |>
    scale_y(grid = TRUE, percent = TRUE)
penguins$body_mass_kg <- penguins$body_mass_g / 1000

obsplot(penguins) |>
    mark_barY(transform_groupX(list(y = "sum"), x = "species", y = "body_mass_kg")) |>
    mark_ruleY(0) |>
    scale_y(grid = TRUE, label = "↑ Total mass (kg)")
obsplot(penguins, height = 150) |>
    mark_dot(y = "species", x = "body_mass_g") |>
    mark_ruleY(
        transform_groupY(list(x1 = "min", x2 = "max"), y = "species", x = "body_mass_g")
    ) |>
    mark_tickX(transform_groupY(list(x = "median"), y = "species", x = "body_mass_g", stroke = "red")) |>
    scale_x(inset = 6) |>
    scale_y(label = NULL) |>
    opts(marginLeft = 60)
data(mobydick1)

obsplot(mobydick1) |>
    mark_barY(
        transform_groupX(y = "count")
    ) |>
    mark_ruleY(0) |>
    scale_y(grid = TRUE)
obsplot(mobydick1) |>
    mark_barY(
        transform_groupX(y = "proportion", filter = JS('d => /[AEIOUY]/.test(d)'))
    ) |>
    mark_ruleY(0) |>
    scale_y(grid = TRUE, percent = TRUE)
data(penguins)

obsplot(penguins) |>
    mark_barY(transform_groupX(y = "count", x = "sex")) |>
    mark_ruleY(0) |>
    facet(x = "species") |>
    scale_x(tickFormat = JS('d => d === null ? "N/A" : d')) |>
    scale_y(grid = TRUE)
obsplot(penguins) |>
    mark_barY(transform_groupX(y = "proportion-facet", x = "sex")) |>
    mark_ruleY(0) |>
    facet(x = "species") |>
    scale_x(tickFormat = JS('d => d === null ? "N/A" : d')) |>
    scale_y(grid = TRUE, percent = TRUE)
obsplot(penguins) |>
    mark_barY(transform_groupX(y = "count", x = "species", fill = "sex")) |>
    mark_ruleY(0) |>
    scale_y(grid = TRUE)
obsplot(penguins, height = 60) |>
    mark_barX(
        transform_stackX(
            transform_groupZ(x = "proportion", fill = "sex")
        )
    ) |>
    mark_text(
        transform_stackX(
            transform_groupZ(
                list(x = "proportion", text = "first"),
                z = "sex", text = "sex")
        )
    ) |>
    mark_ruleX(c(0, 1)) |>
    scale_x(percent = TRUE)
obsplot(penguins) |>
    mark_barY(transform_groupZ(y = "proportion-facet", fill = "sex")) |>
    mark_ruleY(c(0, 1)) |>
    facet(x = "species") |>
    scale_y(grid = TRUE, percent = TRUE)
data(seattle)

obsplot(seattle, height = 300) |>
    mark_cell(
        transform_group(
            fill = "max",
            x = JS('d => d.date.getUTCDate()'),
            y = JS('d => d.date.getUTCMonth()'),
            fill = "temp_max",
            inset = 0.5
        )
    ) |>
    scale_color(scheme = "BuRd") |>
    scale_y(tickFormat = JS('Plot.formatMonth()')) |>
    opts(padding = 0)

Bin transform

data(athletes)

obsplot(athletes) |>
    mark_rectY(transform_binX(y = "count", x = "weight")) |>
    mark_ruleY(0) |>
    scale_y(grid = TRUE)
obsplot(athletes) |>
    mark_rectY(transform_binX(y = "count", x = "weight", inset = 0)) |>
    mark_ruleY(0) |>
    scale_x(round = TRUE) |>
    scale_y(grid = TRUE)
obsplot(athletes) |>
    mark_areaY(transform_binX(y = "count", x = "weight", fill = "#ccc")) |>
    mark_lineY(transform_binX(y = "count", x = "weight")) |>
    mark_ruleY(0) |>
    scale_y(grid = TRUE)
obsplot(athletes) |>
    mark_rectY(transform_binX(y = "count", x = "weight", thresholds = "sturges")) |>
    mark_ruleY(0) |>
    scale_y(grid = TRUE)
obsplot(athletes) |>
    mark_rectY(transform_binX(y = "count", x = "weight", cumulative = TRUE)) |>
    mark_ruleY(0) |>
    scale_y(grid = TRUE)
obsplot(athletes) |>
    mark_rectY(transform_binX(y2 = "count", x = "weight", fill = "sex", mixBlendMode = "multiply")) |>
    mark_ruleY(0) |>
    scale_y(grid = TRUE)
obsplot(athletes) |>
    mark_rectY(transform_binX(y = "count", x = "weight", fill = "sex")) |>
    mark_ruleY(0) |>
    scale_y(grid = TRUE)
obsplot(athletes, height = 60) |>
    mark_barX(transform_binX(fill = "count", x = "weight")) |>
    scale_x(round = TRUE) |>
    scale_color(scheme = "YlGnBu")
obsplot(athletes) |>
    mark_rect(transform_bin(fill = "count", x = "weight", y = "height", inset = 0)) |>
    scale_color(scheme = "YlGnBu") |>
    opts(round = TRUE, grid = TRUE) 
obsplot(athletes) |>
    mark_rect(transform_bin(fillOpacity = "count", x = "weight", y = "height", fill = "sex", inset = 0)) |>
    opts(round = TRUE, grid = TRUE)
obsplot(athletes) |>
    mark_dot(transform_bin(r = "count", x = "weight", y = "height")) |>
    scale_r(range = c(0, 10)) |>
    opts(round = TRUE, grid = TRUE)
obsplot(athletes) |>
    mark_dot(transform_bin(r = "count", x = "weight", y = "height", stroke = "sex")) |>
    scale_r(range = c(0, 10)) |>
    opts(round = TRUE, grid = TRUE)
obsplot(athletes, height = 60) |>
    mark_dot(transform_binX(r = "count", x = "weight")) |>
    scale_r(range = c(0, 14))
sports_by_weight <- levels(reorder(athletes$sport, athletes$weight, median, na.rm = TRUE))

obsplot(athletes, height = 600) |>
    mark_barX(transform_binX(fill = "proportion-facet", x = "weight", inset = 0.5)) |>
    facet(marginLeft = 100, y = "sport") |>
    scale_color(scheme = "YlGnBu") |>
    scale_x(round = TRUE, grid = TRUE) |>
    scale_fy(domain = sports_by_weight, label = NULL) |>
    opts(marginLeft = 100, padding = 0)

Stack transform